package com.invengo.module_check.ui.fragment.change_shelf.fragment;

import android.annotation.SuppressLint;
import android.app.Application;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableList;

import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_rfid.classify.AnalyzeImpl;
import com.invengo.library_rfid.classify.RFIDCallBackListener;
import com.invengo.library_rfid.entity.TagInfo;
import com.invengo.module_check.BR;
import com.invengo.module_check.R;
import com.invengo.module_check.data.repsitory.business.BusinessRepsitory;
import com.invengo.module_check.ui.fragment.change_shelf.fragment.item.ChangeItemViewModel;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import io.reactivex.Observable;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter;
import me.tatarka.bindingcollectionadapter2.ItemBinding;

public class ChangeViewModel extends BaseViewModel<BusinessRepsitory> {
    public static final String CHANGE_BY_BOOK = "ChangeByBookFragment";
    public static final String CHANGE_BY_SHELF = "ChangeByShelfFragment";
    //给RecyclerView添加ObservableList
    //    =====================这部分是根据图书=========================
    public BindingRecyclerViewAdapter adapter = new BindingRecyclerViewAdapter();
    public ObservableList<ChangeItemViewModel> byBookItemList = new ObservableArrayList<>();
    public ItemBinding<ChangeItemViewModel> byBookitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_change_by_book);


    //    =====================这部分是根据层架=========================
    public ObservableField<String> shelfName = new ObservableField<>("");
    public ObservableField<String> shelfCode = new ObservableField<>("");

    public ObservableList<ChangeItemViewModel> byShelfItemList = new ObservableArrayList<>();
    public ItemBinding<ChangeItemViewModel> byShelfitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_change_by_shelf);

    public RFIDCallBackListener rfidService = new RFIDCallBackListener(AnalyzeImpl.TO_BOOK,
            tagInfo -> onScanResult(tagInfo),
            state -> isReading.set(state));

    public ChangeViewModel(@NonNull Application application) {
        super(application, BusinessRepsitory.getInstance());
        registerRFID(rfidService);
    }

    public void onScanResult(TagInfo tagInfo) {
        switch (tagInfo.getRfidModel()) {
            case TID:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF)
                    getShelfByTid(tagInfo.getTag());
                else
                    getBookByTid(tagInfo.getTag());
                break;
            case EPC:
            case U_DATA:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF)
                    getShelfByCode(tagInfo.getTag());
                else
                    getBookByCode(tagInfo.getTag());
                break;
        }
    }

    public UIChangeObservable ui = new UIChangeObservable();

    public class UIChangeObservable {
        public SingleLiveEvent<List<BookBean>> nextEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ShelfBean> selectShelfEvent = new SingleLiveEvent<>();
    }

//    public BindingCommand<String> textChangeCommand = new BindingCommand<>(s -> {
//        getUC().getHideKeyboardEvent().call();
//        getShelfByCode(s);
//    });

    public BindingCommand<String> textChangeCommand = new BindingCommand<>(s -> {
        getUC().getHideKeyboardEvent().call();
        getShelfByCode(s);
    });

    /**
     * 按Tid查询书本
     *
     * @param tid 标签
     */
    private void getBookByTid(String tid) {
        model.getBookByTid(tid)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> {
                    addItem(bookBean);
                });
    }

    /**
     * 按Tid查询书本
     *
     * @param code 标签
     */
    private void getBookByCode(String code) {
        model.getBookByCode(code)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> {
                    addItem(bookBean);
                });
    }

    /**
     * 按书架查询书籍
     *
     * @param shelfCode 标签
     */
    private void getBookByShelfCode(String shelfCode) {
        model.getBookByShelfCode(shelfCode)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .flatMap(bookBeans -> Observable.fromIterable(bookBeans))
                .toList()//李为民有个项目导致的问题
//                .toSortedList((o1,o2)->o1.getPretendCallNo().compareTo(o2.getPretendCallNo()))
                .subscribe(bookBeans -> {
                    for (BookBean bean : bookBeans) {
                       addItem(bean);
                    }
                });
    }

    /**
     * 按tid取架
     *
     * @param tid 时间
     */
    private void getShelfByTid(String tid) {
        model.getShelfInfoByTid(tid)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bean -> {
                    handlerShelf(bean);
                });
    }


    /**
     * 查询货架信息
     *
     * @param shelfCode 标签
     */
    private void getShelfByCode(String shelfCode) {
        model.getShelfInfoByCode(shelfCode)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bean -> {
                    handlerShelf(bean);
                });
    }

    public void handlerShelf(ShelfBean bean) {
        byShelfItemList.clear();
        shelfName.set(bean.getShelfName());
        shelfCode.set(bean.getShelfCode());
        getBookByShelfCode(bean.getShelfCode());
    }

    /**
     * 添加项目
     *
     * @param bean 豆
     */
    private void addItem(BookBean bean) {
//        Optional<BookBean> any;
        switch (getCacheKey()) {
            case CHANGE_BY_BOOK:
//                any = byBookItemList.stream().filter(model -> model.book.getValue().getTid().equals(bean.getTid())).map(model -> model.book.getValue()).findAny();
//                if (!any.isPresent()) {
                byBookItemList.add(new ChangeItemViewModel(this, bean));
//                }
                break;
            case CHANGE_BY_SHELF:
                byShelfItemList.add(new ChangeItemViewModel(this, bean));
                break;
        }
    }

    /**
     * 清空列表
     */
    public BindingCommand cleanByBookCommand = new BindingCommand(() -> {
        cleanRFIDCacheNotStop();
        switch (getCacheKey()) {
            case CHANGE_BY_BOOK:
                byBookItemList.clear();
                break;
            case CHANGE_BY_SHELF:
                byShelfItemList.clear();
                shelfName.set("");
                shelfCode.set("");
                break;
        }

    });

    public void onItemRemove(ChangeItemViewModel model) {
        int position = -1;
        switch (getCacheKey()) {
            case CHANGE_BY_BOOK:
                position = byBookItemList.indexOf(model);
                byBookItemList.remove(position);
                break;
            case CHANGE_BY_SHELF:
                position = byShelfItemList.indexOf(model);
                byShelfItemList.remove(position);
                break;
        }
        adapter.notifyDataSetChanged();
        ToastUtils.showShort("删除成功");
    }

    /**
     * 获取position的方式有很多种,indexOf是其中一种，常见的还有在Adapter中、ItemBinding.of回调里
     *
     * @return
     */
    public int getPosition(ChangeItemViewModel item) {
        switch (getCacheKey()) {
            case CHANGE_BY_BOOK:
                return byBookItemList.indexOf(item);
            case CHANGE_BY_SHELF:
                return byShelfItemList.indexOf(item);
        }
        return -1;
    }


    public BindingCommand changeBookCommand = new BindingCommand(() -> {
        cleanRFIDCache();
        List<BookBean> beans = new ArrayList<>();
        switch (getCacheKey()) {
            case CHANGE_BY_BOOK:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    beans = byBookItemList.stream().map(item -> item.book.getValue()).collect(Collectors.toList());
                }else{
                    beans = StreamSupport.stream(byBookItemList).map(item -> item.book.getValue()).collect(java8.util.stream.Collectors.toList());
                }
                break;
            case CHANGE_BY_SHELF:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    beans = byShelfItemList.stream().map(item -> item.book.getValue()).collect(Collectors.toList());
                }else{
                    beans = StreamSupport.stream(byShelfItemList).map(item -> item.book.getValue()).collect(java8.util.stream.Collectors.toList());
                }
                break;
        }
        ui.nextEvent.postValue(beans);
    });

    public BindingCommand selectShelf = new BindingCommand<>(() -> {
        ShelfBean bean = null;
        if (!TextUtils.isEmpty(shelfName.get()) && !TextUtils.isEmpty(shelfCode.get())) {
            bean = new ShelfBean();
            bean.setShelfName(shelfName.get());
            bean.setShelfCode(shelfCode.get());
        }
        ui.selectShelfEvent.postValue(bean);
    });


}
